import 'package:family_expense/features/income_expense/models/income_expense_detail.dart';
import 'package:family_expense/features/income_expense_search/widgets/income_expense_search_result.dart';
import 'package:my_flutter_core/my_flutter_core.dart';

class IncomeExpenseDetailService {
  final String _url = '/income-expense-detail';
  final HttpRequestService _httpRequestService = HttpRequestService();

  /// Retrieves current user account group [IncomeExpenseDetail] list from backend service.
  Future<List<IncomeExpenseDetail>> queryListWithSummaryByAccountGroup(
    int pageSize,
    int pageIndex,
  ) async {
    // Gets the response of the http get request.
    final response = await _httpRequestService.get(
      '$_url/query-list-with-summary-by-account-group',
      params: {'pageSize': pageSize, 'pageIndex': pageIndex},
    );

    // Parses the data from [Map<String, dynamic>] to [IncomeExpenseDetail].
    return (response.payload as List<dynamic>)
        .map((p) => IncomeExpenseDetail.fromJson(p))
        .toList();
  }

  /// Retrieves current user account group [IncomeExpenseDetail] list from backend service.
  Future<List<IncomeExpenseDetail>> queryListByAccountGroup(
    int pageSize,
    int pageIndex, {
    IncomeExpenseSearchArguments? searchArguments,
  }) async {
    // Gets the response of the http get request.
    // Formats the date parameter to clear the time value.
    final response = await _httpRequestService.get(
      '$_url/query-list-by-account-group',
      params: {
        'pageSize': pageSize,
        'pageIndex': pageIndex,
        'startDate': searchArguments?.startDate.formatLongDateTime(
          dateOnly: true,
        ),
        'endDate': searchArguments?.endDate.formatLongDateTime(dateOnly: true),
        'keyword': searchArguments?.keyword?.trim() ?? '',
        'keywordsSearchCondition':
            searchArguments?.keywordsSearchCondition ??
            IncomeExpenseSearchArguments.keywordsSearchOrCondition,
        'type': searchArguments?.type ?? '',
        'detailType': searchArguments?.detailType ?? '',
        'paymentType': searchArguments?.paymentType ?? '',
        'bankCardId': searchArguments?.bankCard?.id ?? '',
      },
    );

    // Parses the data from [Map<String, dynamic>] to [IncomeExpenseDetail].
    return (response.payload as List<dynamic>)
        .map((p) => IncomeExpenseDetail.fromJson(p))
        .toList();
  }

  /// Retrieves current user account group [IncomeExpenseDetail] total amount from backend service.
  Future<double> queryTotalAmountByAccountGroup({
    required IncomeExpenseSearchArguments searchArguments,
  }) async {
    // Gets the response of the http get request.
    // Formats the date parameter to clear the time value.
    final response = await _httpRequestService.get(
      '$_url/query-total-amount-by-account-group',
      params: {
        'startDate': searchArguments.startDate != null
            ? searchArguments.startDate.formatLongDateTime(dateOnly: true)
            : '',
        'endDate': searchArguments.startDate != null
            ? searchArguments.endDate.formatLongDateTime(dateOnly: true)
            : '',
        'keyword': searchArguments.keyword?.trim() ?? '',
        'keywordsSearchCondition':
            searchArguments.keywordsSearchCondition ??
            IncomeExpenseSearchArguments.keywordsSearchOrCondition,
        'type': searchArguments.type ?? '',
        'detailType': searchArguments.detailType ?? '',
        'paymentType': searchArguments.paymentType ?? '',
        'bankCardId': searchArguments.bankCard?.id ?? '',
      },
    );

    // Returns the data as dobule.
    return response.payload.toDouble();
  }

  /// Retrieves current user account group [IncomeExpenseDetail] list from backend service.
  Future<IncomeExpenseDetail> queryDetails(String id) async {
    // Gets the response of the http get request.
    final response = await _httpRequestService.get(
      '$_url/query-details',
      params: {'id': id},
    );

    // Parses the data from [Map<String, dynamic>] to [IncomeExpenseDetail].
    return IncomeExpenseDetail.fromJson(response.payload);
  }

  /// Retrieves current user account group credit card bill list from backend service.
  Future<List<IncomeExpenseDetail>> queryCreditCardBill(
    int pageSize,
    int pageIndex,
    String bankCardId,
    DateTime statementDate,
  ) async {
    // Gets the response of the http get request.
    final response = await _httpRequestService.get(
      '$_url/query-credit-card-bill',
      params: {
        'pageSize': pageSize,
        'pageIndex': pageIndex,
        'bankCardId': bankCardId,
        'statementDate': statementDate.formatLongDateTime(dateOnly: true),
      },
    );

    // Parses the data from [Map<String, dynamic>] to [IncomeExpenseDetail].
    return (response.payload as List<dynamic>)
        .map((p) => IncomeExpenseDetail.fromJson(p))
        .toList();
  }

  /// Retrieves current user account group credit card bill amount from backend service.
  Future<double> queryCreditCardBillAmount(
    String bankCardId,
    DateTime statementDate,
  ) async {
    // Gets the response of the http get request.
    final response = await _httpRequestService.get(
      '$_url/query-credit-card-bill-amount',
      params: {
        'bankCardId': bankCardId,
        'statementDate': statementDate.formatLongDateTime(dateOnly: true),
      },
    );

    // Returns the data as dobule.
    return response.payload.toDouble();
  }

  /// Retrieves current user account group income/expense coordinates list from backend service.
  Future<List<IncomeExpenseDetail>> queryCoordinates(String year) async {
    // Gets the response of the http get request.
    final response = await _httpRequestService.get(
      '$_url/query-coordinates',
      params: {'year': year},
    );

    // Parses the data from [Map<String, dynamic>] to [IncomeExpenseDetail].
    return (response.payload as List<dynamic>)
        .map((p) => IncomeExpenseDetail.fromJson(p))
        .toList();
  }

  /// Adds the new [IncomeExpenseDetail] to server.
  Future<bool> add(IncomeExpenseDetail incomeExpenseDetail) async {
    final response = await _httpRequestService.post(
      '$_url/add',
      body: incomeExpenseDetail.toJson(),
    );

    return response.success;
  }

  /// Updates the new [IncomeExpenseDetail] to server.
  Future<bool> update(IncomeExpenseDetail incomeExpenseDetail) async {
    final response = await _httpRequestService.post(
      '$_url/update',
      body: incomeExpenseDetail.toJson(),
    );

    return response.success;
  }

  /// Updates the new [IncomeExpenseDetail] to server.
  Future<bool> delete(String? id) async {
    final response = await _httpRequestService.post(
      '$_url/delete',
      body: {'id': id},
    );

    return response.success;
  }
}
